<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<meta http-equiv="X-UA-Compatible" content="ie=edge" />
		<title>坐标变换</title>
		<style>
			* {
                margin: 0;
                padding: 0;
                vertical-align: middle;
            }
			
			canvas{
				width: 100vw;
				max-width: 1024px;
			}
        </style>
	</head>

	<body>
		<h1>将伪3d视角的地图，转换到俯瞰的视角</h1>
		<h5>可以点击下方按钮，把上次做到一半的地图照片导入进来不加载地图也可以，就是得重新绘制地图</h5>
		<div id="upload">加载地图<input type="file" id="add-upload-input" accept="image/*" class="page2-btn-upload button" /></div>
		<br>

		<h2 id="working-hint"></h2>

		<h1>原图</h1>
		<canvas id="cvs"></canvas>

		<h1>俯瞰</h1>
		<canvas id="cvs2"></canvas>

		<canvas id="cvs3"></canvas>


		<h1>生成结果</h1>
		<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
		<script type="text/javascript" src="../linear/axis.js"></script>
		<script>
			const SQRT_3 = Math.sqrt(3);
			const SQRT_3_3 = SQRT_3 / 3;
			const IMAGE_WIDTH = 2048;
			let appModel = {
				axisTickWidth: 25, // 坐标轴刻度步长
				axisTransform: {
					i: {
						x: 0.5,
						y: 0.5,
					},
					j: {
						x: -SQRT_3 * 0.5,
						y: SQRT_3 * 0.5,
					},
				},
				axisReverse: {
					i: {
						x: 1,
						y: -1 / SQRT_3,
					},
					j: {
						x: 1,
						y: 1 / SQRT_3,
					},
				},
				canvasInfo: {
					width: 0,
					height: 0,
				},
				transformMatrix: {
					a: 0,
					b: 0,
					c: 0,
					d: 0,
				},
			};

			let appController = {
				init: function() {
					appModel.canvasInfo.width = appModel.canvasInfo.height = IMAGE_WIDTH;
				},
				getModel() {
					return appModel;
				},
			};

			let appView = {
				canvas: document.getElementById('cvs'),
				ctx: null,
				canvas2: document.getElementById('cvs2'),
				ctx2: null,
				canvas3: document.getElementById('cvs3'),
				ctx3: null,
				axis: null,
				axis2: null,
				axis3: null,
				imgData: [],
				$addUploadInput: $('#add-upload-input'),
				$workingHint: $('#working-hint'),
				init: async function() {
					appView.$addUploadInput.change(appView.uploadImageHandler);

					appView.ctx = appView.initCanvas(appView.canvas);
					appView.ctx2 = appView.initCanvas(appView.canvas2);
					appView.ctx3 = appView.initCanvas(appView.canvas3);
					appView.initAxis();
					appView.initAxis2();
					appView.initAxis3();

				},
				initCanvas: function(canvas, per = 1) {
					const model = appController.getModel();
					canvas.width = model.canvasInfo.width * per;
					canvas.height = model.canvasInfo.height * per;
					let ctx = canvas.getContext('2d');
					ctx.rect(
						0,
						0,
						model.canvasInfo.width,
						model.canvasInfo.height
					);
					ctx.fillStyle = '#000000';
					ctx.fill();
					return ctx;
				},
				initAxis() {
					const model = appController.getModel();
					appView.axis = new axis(
						50,
						50,
						model.axisTickWidth,
						appView.ctx, {
							x: IMAGE_WIDTH / 2,
							y: IMAGE_WIDTH / 2,
						}
					);
				},
				initAxis2() {
					const model = appController.getModel();
					appView.axis2 = new axis(
						50,
						50,
						model.axisTickWidth,
						appView.ctx2, {
							x: IMAGE_WIDTH / 2,
							y: IMAGE_WIDTH / 2,
						},
						model.axisTransform
					);
				},
				initAxis3() {
					const model = appController.getModel();
					appView.axis3 = new axis(
						50,
						50,
						model.axisTickWidth,
						appView.ctx3, {
							x: IMAGE_WIDTH / 2,
							y: IMAGE_WIDTH / 2,
						},
						model.axisReverse
					);
				},
				uploadImageHandler: function(e) {
					const model = appController.getModel();
					let file = e.target.files[0];
					let _temp, datas;
					// 确认选择的文件是图片
					if (file.type.indexOf('image') != 0) return;
					let reader = new FileReader();
					reader.readAsDataURL(file);
					reader.onload = async function(e) {
						// 图片base64化
						// let newUrl = this.result;
						// let image = new Image();
						// image.src = e.target.result;
						// image.onload = function() {
						// 	_temp = document.getElementById('canvas-upload-image');
						// 	_temp = _temp.getContext('2d');
						// 	_temp.drawImage(image, 0, 0);
						// 	appView.readDatasToMap(_temp.getImageData(0, 0, model.result_canvas_total_width, model.result_canvas_total_height)
						// 		.data);
						// }

						await appView.initImage(e.target.result);
						// appView.reverseImage();
						appView.creatAndRender(50);

						// 渲染坐标轴
						appView.axis.render();
						appView.axis2.render();
						appView.axis3.render();
					}
				},
				initImage(src) {
					return new Promise((res, rej) => {
						console.log(`init image start`);
						appView.$workingHint.text('图片处理中...');
						let imgData = [];
						let imgDataTransformed = [];
						let img = new Image();
						img.onload = function() {
							console.log(`init image loaded`);
							const center = appView.axis.center;
							appView.ctx.drawImage(
								img,
								center.x - img.width / 2,
								center.y - img.height / 2
							);

							let sourceData = appView.ctx.getImageData(
								center.x - img.width / 2,
								center.y - img.height / 2,
								img.width,
								img.height
							).data;

							for (let y = 0, index = 0; y < img.height; y++) {
								for (let x = 0; x < img.width; x++, index++) {
									let r = sourceData[index * 4];
									let g = sourceData[index * 4 + 1];
									let b = sourceData[index * 4 + 2];

									let color = `rgb(${r}, ${g}, ${b})`;

									appView.renderTransformPoint(index, color);
								}
							}
							console.log(`init image complete`);
							appView.$workingHint.text('图片处理完成');
							res();
						};
						// img.src = '../../img/新加坡工程文件.jpg';
						img.src = src;
					});
				},
				renderTransformPoint(index, color) {
					const tickWidth = appController.getModel().axisTickWidth;
					let x = ((index - 1) % IMAGE_WIDTH) - IMAGE_WIDTH / 2;
					let y = -Math.floor((index - 1) / IMAGE_WIDTH) +
						IMAGE_WIDTH / 2;
					let p = new point(
						x / tickWidth,
						y / tickWidth,
						appView.axis2
					);
					p.render(appView.ctx2, color);
				},
				reverseImage() {
					console.log(`reverse image start`);

					let sourceData = appView.ctx2.getImageData(
						0,
						0,
						IMAGE_WIDTH,
						IMAGE_WIDTH
					).data;

					for (let y = 0, index = 0; y < IMAGE_WIDTH; y++) {
						for (let x = 0; x < IMAGE_WIDTH; x++, index++) {
							let r = sourceData[index * 4];
							let g = sourceData[index * 4 + 1];
							let b = sourceData[index * 4 + 2];

							let color = `rgb(${r}, ${g}, ${b})`;

							appView.renderReversePoint(index, color);
						}
					}
					console.log(`init image complete`);
				},
				renderReversePoint(index, color) {
					const tickWidth = appController.getModel().axisTickWidth;
					let x = ((index - 1) % IMAGE_WIDTH) - IMAGE_WIDTH / 2;
					let y = -Math.floor((index - 1) / IMAGE_WIDTH) +
						IMAGE_WIDTH / 2;
					let p = new point(
						x / tickWidth,
						y / tickWidth,
						appView.axis3
					);
					p.render(appView.ctx3, color);
				},
				creatAndRender(per) {
					let h = document.createElement('h1');
					h.innerText = per + '%';


					const realPer = per / 100;
					const model = appController.getModel();
					let canvas = document.createElement('canvas');
					canvas.width = model.canvasInfo.width * realPer;
					canvas.height = model.canvasInfo.height * realPer;
					let ctx = canvas.getContext('2d');
					ctx.rect(0, 0, model.canvasInfo.width, model.canvasInfo.height);
					ctx.fillStyle = '#000000';
					ctx.fill();

					let delta = (1 - realPer) / 2;
					ctx.drawImage(appView.canvas2, -1 * delta * IMAGE_WIDTH, -1 * delta * IMAGE_WIDTH);

					document.body.appendChild(h);
					document.body.appendChild(canvas);
				}
			};

			appController.init();
			appView.init();
		</script>
	</body>
</html>
